/*
 * Copyright (c) 2002 Boris Pruessmann and others. All rights reserved. This
 * program and the accompanying materials are made available under the terms of
 * the Common Public License v0.5 which accompanies this distribution, and is
 * available at http://www.eclipse.org/legal/cpl-v05.html
 *
 * Contributors: Boris Pruessmann - Initial implementation.
 */
package net.sourceforge.perforce.ui;

import java.util.Map;

import org.eclipse.core.resources.IResource;
import org.eclipse.jface.preference.IPreferenceStore;

/**
 * @version $Revision: 489 $
 * @author <a href="mailto:bpruessmann@users.sourceforge.net">Boris
 *         Pruessmann</a>
 */
public class P4DecoratorConfiguration {
  //----------------------------------------------------------------------------
  // Public Constants

  /** Binding for resource name. */
  public static final String RESOURCE_NAME = "name"; //$NON-NLS-1$
  /** Binding for resource have revision. */
  public static final String HAVE_REV = "have_rev"; //$NON-NLS-1$
  /** Binding for resource head revision. */
  public static final String HEAD_REV = "head_rev"; //$NON-NLS-1$

  /** Binding for repository p4port. */
  public static final String P4PORT = "p4port"; //$NON-NLS-1$
  /** Binding for repository p4client. */
  public static final String P4CLIENT = "p4client"; //$NON-NLS-1$
  /** Binding for repository p4user. */
  public static final String P4USER = "p4user"; //$NON-NLS-1$

  /** Binding for "dirty" resource state. */
  public static final String DIRTY_FLAG = "dirty_flag"; //$NON-NLS-1$
  /** Binding for "dirty" resource state. */
  public static final String DIRTY_FLAG_2 = "dirty_flag_2"; //$NON-NLS-1$
  /** Default binding for "dirty" flag. */
  public static final String DEFAULT_DIRTY_FLAG = ">"; //$NON-NLS-1$
  /** Default binding for "added" flag. */
  public static final String DEFAULT_ADDED_FLAG = "*"; //$NON-NLS-1$

  /** Default decoration format for files. */
  public static final String DEFAULT_FILETEXTFORMAT = "{dirty_flag}{name} {have_rev}"; //$NON-NLS-1$
  /** Default decoration format for folders. */
  public static final String DEFAULT_FOLDERTEXTFORMAT = "{dirty_flag}{name}"; //$NON-NLS-1$
  /** Default decoration format for projects. */
  public static final String DEFAULT_PROJECTTEXTFORMAT = "{dirty_flag}{name} [{p4port}]"; //$NON-NLS-1$

  // ---------------------------------------------------------------------------
  // Private Constants

  /** prefix character that can be removed if the following binding is not found */
  private static final char KEYWORD_SEPCOLON = ':';
  /** prefix character that can be removed if the following binding is not found */
  private static final char KEYWORD_SEPAT = '@';

  // ------------------------------------------------------------------------
  // Private Constructors

  /** Constructor for P4DecoratorConfiguration. */
  private P4DecoratorConfiguration() {
  }

  // -----------------------------------------------------------------------
  // Public Static Methods

  /**
   * Returns the text format for given resource.
   *
   * @param resource the resource.
   * @return the text format.
   */
  public static String getFormat(IResource resource) {
    IPreferenceStore store = PerforceUIPlugin.getPlugin().getPreferenceStore();
    String format = null;

    switch (resource.getType()) {
      case IResource.PROJECT:
        format = store.getString(IPerforceUIConstants.PREF_PROJECTTEXTFORMAT);
        break;

      case IResource.FOLDER:
        format = store.getString(IPerforceUIConstants.PREF_FOLDERTEXTFORMAT);
        break;

      default:
        format = store.getString(IPerforceUIConstants.PREF_FILETEXTFORMAT);
        break;
    }

    return format;
  }

  /**
   * Called to perform the binding for the given format and bindings.
   *
   * @param format the text format string.
   * @param bindings map containing the bindings.
   * @return the finished string.
   */
  public static String bind(String format, Map<String, String> bindings) {
    StringBuilder result = new StringBuilder(80);
    int length = format.length();
    int start = -1;
    int end = length;
    while (true) {
      if ((end = format.indexOf('{', start)) > -1) {
        result.append(format.substring(start + 1, end));
        if ((start = format.indexOf('}', end)) > -1) {
          String s = bindings.get(format.substring(end + 1, start));
          if (s != null) {
            result.append(s);
          } else {
            // support for removing prefix character if binding is null
            int curLength = result.length();
            if (curLength > 0) {
              char c = result.charAt(curLength - 1);
              if (c == KEYWORD_SEPCOLON || c == KEYWORD_SEPAT) {
                result.deleteCharAt(curLength - 1);
              }
            }
          }
        } else {
          result.append(format.substring(end, length));
          break;
        }
      } else {
        result.append(format.substring(start + 1, length));
        break;
      }
    }
    return result.toString();
  }
}
